﻿using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ThresholdAssistant.Autofac;
using ThresholdAssistant.DataContract.Result;
using ThresholdAssistant.NLogSdk;
using ThresholdAssistant.WebAPI.Models.Constants;
using ThresholdAssistant.WebAPI.Repository;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThresholdAssistant.WebAPI.Service
{
    /// <summary>
    /// 官方微信服务
    /// </summary>
    public class OfficialWechatService : BaseService, IBaseAutofac
    {
        private static readonly WechatApiClientOptions options = new WechatApiClientOptions()
        {
            AppId = AppSettingConstant.WechatAuthLoginGonfig.AppId,
            AppSecret = AppSettingConstant.WechatAuthLoginGonfig.Secret,
            PushToken = "Token",
            PushEncodingAESKey = "tGIp3dFNVG5pz2DpkoE5iFql2prlPLbdGNqizo0Aq2S"
        };

        private static readonly WechatApiClient client = new WechatApiClient(options);

        /// <summary>
        /// 检测文案是否合法
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public async Task<ContractResult> CheckMsgSecCheckAsync(string openid, string content)
        {
            var result = new ContractResult();
            var token = await CgiBinTokenAsync();
            if (string.IsNullOrWhiteSpace(token))
            {
                return result.SetError("-1", "CgiBin获取Token失败");
            }

            var request = new WxaMessageSecurityCheckRequest()
            {
                OpenId = openid,
                AccessToken = token,
                Scene = 1,
                Version = 2,
                Content = content
            };
            try
            {
                var response = await client.ExecuteWxaMessageSecurityCheckAsync(request);
                var details = response.DetailList;
                if (details != null && details.Any())
                {
                    foreach (var item in details)
                    {
                        if (item.Label != null && item.Label != 100)
                        {
                            return result.SetError("-1", "该文案包含敏感词汇");
                        }
                    }
                }


                result.Success = response.ErrorCode == 0;
                result.ErrorCode = response.ErrorCode.ToString();
                result.ErrorMessage = response.ErrorMessage;

                return result;
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"【调用检测接口失败】请求参数{JsonConvert.SerializeObject(request)},失败原因:{ex}");
            }
            return result.SetError("-1", "调用官方检测接口失败");
        }

        /// <summary>
        /// 检测媒体是否合法
        /// </summary>
        /// <param name="openid"></param>
        /// <param name="url"></param>
        /// <param name="mediaType">媒体类型 1:音频;2:图片</param>
        /// <returns></returns>
        public async Task<ContractResult<string>> CheckMediaAsync(string openid, string url, int mediaType = 2)
        {
            var result = new ContractResult<string>();
            var token = await CgiBinTokenAsync();
            if (string.IsNullOrWhiteSpace(token))
            {
                return result.SetError("-1", "CgiBin获取Token失败");
            }

            var request = new WxaMediaCheckRequest()
            {
                OpenId = openid,
                AccessToken = token,
                Scene = 1,
                Version = 2,
                MediaUrl = url,
                MediaType = mediaType,
            };
            try
            {
                var response = await client.ExecuteWxaMediaCheckAsync(request);

                result.Success = response.ErrorCode == 0;
                result.ErrorCode = response.ErrorCode.ToString();
                result.ErrorMessage = response.ErrorMessage;
                result.Data = response.TraceId ?? "";
                return result;
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"【调用检测接口失败】请求参数{JsonConvert.SerializeObject(request)},失败原因:{ex}");
            }
            return result.SetError("-1", "调用官方检测接口失败");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<string> CgiBinTokenAsync()
        {
            try
            {
                var responese = await client.ExecuteCgibinTokenAsync(new CgibinTokenRequest());
                return responese?.AccessToken;
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"【获取微信官方Token失败】,失败原因{ex}");
            }
            return "";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<string> CallbackAsync(string signature, string timestamp, string nonce, string echostr)
        {
            /* 验证微信服务器 */
            bool ret = client.VerifyEventSignatureForEcho(
                callbackTimestamp: timestamp,
                callbackNonce: nonce,
                callbackSignature: signature
            );
            string callbackJson = "{ ... }";
            var callbackModel = client.DeserializeEventFromJson<SKIT.FlurlHttpClient.Wechat.Api.Events.WxaMediaCheckEvent>(callbackJson);
            //using var reader = new StreamReader(Request.Body, Encoding.UTF8);
            //string content = await reader.ReadToEndAsync();


            if (ret)
            {
                return echostr;
            }

            return "";
        }

        /// <summary>
        /// 检测图片是否合法
        /// </summary>
        /// <param name="fileBytes">媒体图片</param>
        /// <returns></returns>
        public async Task<ContractResult> CheckImageAsync(byte[] fileBytes)
        {
            var result = new ContractResult();
            var token = await CgiBinTokenAsync();
            if (string.IsNullOrWhiteSpace(token))
            {
                return result.SetError("-1", "CgiBin获取Token失败");
            }

            var request = new WxaImageSecurityCheckRequest()
            {
                AccessToken = token,
                FileBytes = fileBytes
            };
            try
            {
                var response = await client.ExecuteWxaImageSecurityCheckAsync(request);

                NLogUtil.Info($"【调用检图片测接口】请求参数{JsonConvert.SerializeObject(request)},响应结果:{JsonConvert.SerializeObject(response)}");

                result.Success = response.ErrorCode == 0;
                result.ErrorCode = response.ErrorCode.ToString();
                result.ErrorMessage = response.ErrorMessage;
                return result;
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"【调用检测接口失败】请求参数{JsonConvert.SerializeObject(request)},失败原因:{ex}");
            }
            return result.SetError("-1", "调用官方检测接口失败");
        }
    }
}
